﻿#region

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Threading;
using Jiubang.Sql;
using log4net;
using UserCL;

#endregion

namespace Jiubang.Wap{
    /// <summary>
    ///   用户ua信息相关操作类。
    /// </summary>
    public sealed class UserUAHelper{
        private static readonly UserUaInfo defaultInfo = new UserUaInfo();
        private static readonly UserUAHelper instance = new UserUAHelper();

        private static readonly ILog log = LogManager.GetLogger(typeof (UserUAHelper));

        private static readonly Timer timer;
        private static readonly UAMos uaMos = new UAMos();
        private static Dictionary<int, UserUaInfo> uaCollectionsById = new Dictionary<int, UserUaInfo>(10);
        private static Dictionary<string, UserUaInfo> userUaInfos = new Dictionary<string, UserUaInfo>(10);

        static UserUAHelper(){
            timer = new Timer(o => LoadUserUaInfo(), null, TimeSpan.FromSeconds(5),
                              TimeSpan.FromSeconds(10));
        }

        private UserUAHelper(){
        }

        ///<summary>
        ///</summary>
        public static UserUAHelper Instance{
            get { return instance; }
        }

        /// <summary>
        ///   获取用户Ua信息,当无法获取到时，返回一个实例化的空对象。
        /// </summary>
        /// <returns></returns>
        public UserUaInfo GetUserUaInfo(){
            UserUaInfo info;

            //先根据gg号判断
            var userId = UserSession.CurrentUser.UserId;
            //登录用户优先判断绑定机型。
            if (userId > 0){
                string a, b, c;
                int uaid, pid;
                uaMos.getUA(UserSession.CurrentUser.UserId, out pid, out a, out b, out uaid, out c);
                if (uaid > 0 && uaCollectionsById.TryGetValue(uaid, out info)){
                    if (log.IsDebugEnabled)
                        log.Debug(string.Format("已找到【userid={0}】的Ua为：{1},width={2},height={3}", userId, info.Model,
                                                info.ScreenWidth, info.ScreenHeight));
                    return info;
                }
            }

            //再根据当前连接中的gaid判断
            var userAgent = Page.GetUserAgent();
            if (!string.IsNullOrEmpty(userAgent)){
                userAgent = userAgent.ToLower();
                //直接命中
                if (userUaInfos.TryGetValue(userAgent, out info)){
                    if (log.IsDebugEnabled)
                        log.Debug(string.Format("已找到【gaid={0}】的Ua为：{1},width={2},height={3}", userAgent, info.Model,
                                                info.ScreenWidth, info.ScreenHeight));
                    return info;
                }
                //遍历寻找
                foreach (var uaInfo in userUaInfos){
                    if (string.IsNullOrEmpty(uaInfo.Value.EnModelName)) continue;
                    if (!uaInfo.Value.EnModelName.Contains(userAgent) && !userAgent.Contains(uaInfo.Value.EnModelName))
                        continue;
                    if (log.IsDebugEnabled)
                        log.Debug(string.Format("已找到【gaid={0}】的Ua为：{1},width={2},height={3}", userAgent,
                                                uaInfo.Value.Model, uaInfo.Value.ScreenWidth, uaInfo.Value.ScreenHeight));
                    return uaInfo.Value;
                }
                if (log.IsDebugEnabled) log.Debug("根据机型号【" + userAgent + "】无法找到相应的基本信息。");
            }
            return defaultInfo;
        }

        private static void LoadUserUaInfo(){
            try{
                log.Debug("开始加载手机型号数据。");
                var cmd = new SqlCommand("MobileBaseInfo_GetList"){CommandType = CommandType.StoredProcedure};
                using (var dr = new SqlHelper("MobileBaseInfo").CreateReader(cmd)){
                    if (!dr.HasRows) return;
                    var dict = new Dictionary<string, UserUaInfo>(4000);
                    var dict2 = new Dictionary<int, UserUaInfo>(4000);
                    while (dr.Read()){
                        var info = new UserUaInfo{
                                                     UaId = Convert.ToInt32(dr["Id"]),
                                                     Model = dr["model"].ToString(),
                                                     EnModelName =
                                                         dr["EnModelName"] == DBNull.Value
                                                             ? ""
                                                             : dr["EnModelName"].ToString().Trim().ToLower(),
                                                     CnModelName = dr["CnModelName"] as string,
                                                     ScreenWidth =
                                                         dr["ScreenWidth"] == DBNull.Value
                                                             ? 0
                                                             : Convert.ToInt32(dr["ScreenWidth"]),
                                                     ScreenHeight =
                                                         dr["ScreenHeight"] == DBNull.Value
                                                             ? 0
                                                             : Convert.ToInt32(dr["ScreenHeight"]),
                                                     OperationSystem = dr["OperationSystem"] as string,
                                                     BrandChineseName = dr["BrandChineseName"] as string,
                                                     BrandEnglishName = dr["BrandEnglishName"] as string,
                                                     ScreenTextWidth = dr["TextWidth"] == DBNull.Value ? 0 : Convert.ToInt32(dr["TextWidth"])
                                                 };
                        if (info.ScreenTextWidth == 0) info.ScreenTextWidth = info.ScreenWidth;
                        dict[info.EnModelName] = info;
                        dict2[info.UaId] = info;
                        if (log.IsDebugEnabled)
                            log.Debug(info.EnModelName + "," + info.ScreenWidth + "," + info.ScreenHeight);
                    }
                    log.Debug("加载手机型号完毕，总计数量：" + dict.Count);
                    userUaInfos = dict;
                    uaCollectionsById = dict2;
                }
            } catch (Exception exception){
                log.Error(exception);
            } finally{
                if (timer != null) timer.Dispose();
            }
        }

        #region Nested type: UserUaInfo

        ///<summary>
        ///</summary>
        public class UserUaInfo{
            /// <summary>
            ///   手机型号Id
            /// </summary>
            public int UaId { get; set; }

            /// <summary>
            ///   手机型号
            /// </summary>
            public string Model { get; set; }

            /// <summary>
            ///   英文手机型号名
            /// </summary>
            public string EnModelName { get; set; }

            /// <summary>
            ///   中文手机型号名
            /// </summary>
            public string CnModelName { get; set; }

            /// <summary>
            ///   手机操作系统名称
            /// </summary>
            public string OperationSystem { get; set; }

            /// <summary>
            ///   屏幕宽度(该属性针对图片显示)
            /// </summary>
            public int ScreenWidth { get; set; }
            /// <summary>
            /// 屏幕宽度(该属性针对文字显示)
            /// </summary>
            public int ScreenTextWidth { get; set; }
            /// <summary>
            ///   屏幕高度
            /// </summary>
            public int ScreenHeight { get; set; }

            /// <summary>
            ///   品牌英文名称
            /// </summary>
            public string BrandEnglishName { get; set; }

            /// <summary>
            ///   品牌中文名称
            /// </summary>
            public string BrandChineseName { get; set; }
        }

        #endregion
    }
}